package com.qiyu.proxy.starter.javaassist;

import javassist.*;

/**
 * @Author linhao
 * @Date created in 7:09 下午 2020/12/6
 */
public class JavaassistProxy<T> {

    private Class clazz;
    private Object proxyObject;

    public JavaassistProxy(Class clazz) {
        this.clazz = clazz;
    }

    private JavaassistProxy(){
    }

    private static final String PROXY_CLASS_SUFFIX="$Proxy";
    private static final String PROXY_METHOD_SUFFIX="$Proxy";

    /**
     * 获取代理对象
     *
     * @return
     */
    private T getProxyObject() throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException {
        T proxyObject = null;
        ClassPool classPool = ClassPool.getDefault();
        //创建代理对象
        CtClass ctClass = classPool.makeClass(this.getPackageName() +"."+ this.getProxyClassName());
        //创建代理对象的接口
        CtClass ctClassInterface = classPool.getCtClass(getPackageName()+"."+clazz.getSimpleName());
        CtClass[] ctInterfaces = new CtClass[]{ctClassInterface};
        ctClass.setInterfaces(ctInterfaces);

        //从接口获取方法
        CtMethod[] methods = ctClassInterface.getDeclaredMethods();
        for (CtMethod method : methods) {
            String methodName = method.getName();
            if("testStr".equals(methodName)){
                /**
                 * 参数解释：
                 * 返回类型
                 * 方法名称
                 * 方法参数类型
                 * 该方法定义存在哪个类里
                 */
                CtMethod newCtmethod = new CtMethod(method.getReturnType(),methodName,method.getParameterTypes(),ctClass);
                newCtmethod.setBody("System.out.println(\"this is test\");");
                ctClass.addMethod(newCtmethod);
            } else if ("testStr".equals(methodName)){

            }
        }
        Class aClass = ctClass.toClass();
        proxyObject = (T) aClass.newInstance();
        return proxyObject;
    }

    private String getPackageName(){
        return clazz.getPackage().getName();
    }

    private String getProxyClassName() {
        return clazz.getSimpleName()+PROXY_CLASS_SUFFIX;
    }

    public static void main(String[] args) throws CannotCompileException, InstantiationException, NotFoundException, IllegalAccessException {
        JavaassistProxy<IStu> javaassistProxy = new JavaassistProxy(IStu.class);
        IStu stuImpl = javaassistProxy.getProxyObject();
        stuImpl.testStr();
    }
}
